home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 15 / BBS in a box XV-2.iso / Files II / Prog / A / ACL 1.0.sit / ACL / Examples / ACL-World / Sources / Collisions.cp / Collisions.cp
Encoding:
Text File  |  1994-09-02  |  10.1 KB  |  437 lines  |  [TEXT/MMCC]

  1.  
  2. /********************************************
  3.  **** ACL-World
  4.  ****
  5.  **** Controls.cp
  6.  ****
  7.  **** Created:      26 August 1994
  8.  **** Modified:     02 Septembre 1994
  9.  **** Version:      0
  10.  **** Compatible:   C++, Mac System 7
  11.  ****
  12.  **** Description:    Collisions demo.
  13.  ****
  14.  *******************/
  15.  
  16. #include "ACL-World.h"
  17.  
  18. //*************************************
  19.  
  20.  
  21.  
  22. static const short PICT_PERS         = 159;
  23. static const short PICT_SIREN         = 158;
  24. static const short PICT_SONG         = 161;
  25. static const short PICT_SPACESHIP     = 164;
  26. static const short PICT_SHIPFIRE     = 165;
  27. static const short PICT_ENEMY         = 166;
  28. static const short PICT_ENEMYFIRE    = 167;
  29. static const short PICT_SPACESHIP2     = 168;
  30. static const short PICT_ENEMY2         = 169;
  31. static const short PICT_FIELD         = 170;
  32.  
  33.  
  34. static AnimFrameDef anim_pers[]         =     {{PICT_PERS+1,NULL,0,0,0,afcmd_endsequence},
  35.                                               {PICT_PERS,NULL,0,0,0,afcmd_endanim}};
  36.  
  37.  
  38. static AnimFrameDef anim_spaceship[]     =     {{PICT_SPACESHIP,NULL,0,0,0,afcmd_endsequence},
  39.                                              {PICT_SPACESHIP2,NULL,0,0,0,afcmd_endanim}};
  40.  
  41.  
  42. static AnimFrameDef anim_enemy[]         =     {{PICT_ENEMY,NULL,0,0,0,afcmd_endsequence},
  43.                                              {PICT_ENEMY2,NULL,0,0,0,afcmd_endanim}};
  44.  
  45.  
  46. static AnimFrameDef anim_song[]     =     {{PICT_SONG+0,NULL,10,0,0,afcmd_frame},
  47.                                          {PICT_SONG+1,NULL,10,0,0,afcmd_frame},                                    
  48.                                          {PICT_SONG+2,NULL,90,0,0,afcmd_endanim}};        
  49.  
  50. static AnimFrameDef anim_field[]     =     {{PICT_FIELD+0,NULL,1,0,0,afcmd_frame},
  51.                                          {PICT_FIELD+1,NULL,1,0,0,afcmd_frame},                                    
  52.                                          {PICT_FIELD+2,NULL,1,0,0,afcmd_endsequence},
  53.                                         {PICT_FIELD+3,NULL,1,0,0,afcmd_frame},
  54.                                          {PICT_FIELD+4,NULL,1,0,0,afcmd_frame},                                    
  55.                                          {PICT_FIELD+5,NULL,1,0,0,afcmd_endanim}};        
  56.  
  57.  
  58. //*************************************
  59.  
  60. #define    TEXTSTEP1    "\pAt any time you can detect if an object collides with another. ACL uses a fast algorithm which allows real time collision detection at the pixel precision."
  61.  
  62. #define    TEXTSTEP2    "\pExamine this new example. You can move the spaceship with the arrows of the keyboard and fire with the space bar."
  63.  
  64. #define    TEXTSTEP3    "\pIn this situation not all objects should produce collisions. For example the enemy rockets should not collide with spaceship laser and the spaceship should not collide with its laser shooting."
  65.  
  66. #define    TEXTSTEP4    "\pACL allows each moveable object to have a collision key. The first part of the key defines the type of the object and the second part indicates which object should produce collision with the specified type."
  67.  
  68. #define    TEXTSTEP5    "\pComposed animations produce standard collisions. Each part of the composed anim is considered like a single object and is able to produce collision. In this example the field of the spaceship is a sub-object of the spaceship animation. "
  69.                      
  70.                                  
  71.                     
  72. //*************************************
  73.  
  74. static AnimGfx        *background;
  75. static short        backwidth,backheight;
  76. static Anim            *anims[3];
  77. static AnimControl    controls[2];
  78. static AnimControl    spaceshipcontrols[1], firecontrols[1], enemycontrols[2], enemyfirecontrols[2];
  79. static short        anim_h,anim_w;
  80. static AnimBase        *animbase;
  81.  
  82. //*************************************
  83.  
  84. unsigned short ranged_rdm( unsigned short min, unsigned short max )
  85. {
  86.     unsigned short qdRdm;
  87.     unsigned long    range, t;
  88.  
  89.     qdRdm = Random();
  90.     range = max - min;
  91.     t = (qdRdm * range) / 65536;
  92.     return( t+min );
  93. }
  94.  
  95.  
  96. Boolean    testanimsong(AnimCObject *a, AnimControl *c)
  97. {
  98.  
  99.     if (anims[2]->checkcollision(anims[0]))
  100.     {
  101.         if (anims[0]->getcurrentsequence()!=1) anims[0]->setsequence(1);
  102.     }
  103.     else if (anims[0]->getcurrentsequence()!=0) anims[0]->setsequence(0);
  104.  
  105.  
  106.     return TRUE;
  107. }
  108.  
  109. Boolean    testrandomsong(AnimCObject *a, AnimControl *c)
  110. {
  111.  
  112.     controls[1].y = ranged_rdm(anims[0]->gety(),anims[0]->gety()+anim_h);
  113.     anims[2]->setcurrentframe(0);
  114.  
  115.     return TRUE;
  116. }
  117.  
  118. Boolean    testspaceship(AnimCObject *a, AnimControl *c)
  119. {
  120.     if (c->x<0 && a->getx()+c->x>0) return TRUE;
  121.     else if (c->x>0 && a->getx()+c->x<backwidth-anim_w) return TRUE;
  122.  
  123.     return FALSE;
  124. }
  125.  
  126.  
  127. Boolean    testfire(AnimCObject *a, AnimControl *c)
  128. {
  129.     short h;
  130.  
  131.     h = ((Anim*)a)->getcurrentframe()->getheight();
  132.  
  133.     if (a->gety() <= -h) a->setdeletenextupdate(TRUE);
  134.     
  135.     if (a->checkcollision(anims[1]))
  136.     {
  137.         if (anims[1]->getcurrentsequence()!=1) anims[1]->setsequence(1);
  138.         a->setdeletenextupdate(TRUE);
  139.     }
  140.  
  141.     return TRUE;
  142. }
  143.  
  144.  
  145. Boolean    testenemyfire(AnimCObject *a, AnimControl *c)
  146. {
  147.  
  148.     if (a->checkcollision(anims[0]))
  149.     {
  150.         if (anims[0]->getcurrentsequence()!=1) anims[0]->setsequence(1);
  151.         a->setdeletenextupdate(TRUE);        
  152.     }
  153.  
  154.     if (anims[2])
  155.     {
  156.         if (a->checkcollision(anims[2]))
  157.         {
  158.             if (anims[2]->getcurrentsequence()!=1) anims[2]->setsequence(1,FALSE);
  159.             
  160.             a->setdeletenextupdate(TRUE);        
  161.         }
  162.     }
  163.  
  164.     return TRUE;
  165. }
  166.  
  167.  
  168. Boolean    testenemy(AnimCObject *a, AnimControl *c)
  169. {
  170.     Anim *anim;
  171.  
  172.     short w,h;
  173.  
  174.     w = ((Anim*)a)->getcurrentframe()->getwidth();
  175.     h = ((Anim*)a)->getcurrentframe()->getheight();
  176.  
  177.     if (a->getx()>=backwidth) return TRUE;
  178.  
  179.     if ( (( ((short)a->getx()) % 10)==0) && ranged_rdm(0,2))
  180.     {
  181.         anim = animbase->createanim(PICT_ENEMYFIRE);
  182.         anim->setcollisionkey_me(1);
  183.         anim->setcollisionkey_hit(2);
  184.  
  185.         anim->place(a->getx()+(w/2),a->gety()+(h/2) );
  186.  
  187.  
  188.         w = anims[0]->getcurrentframe()->getwidth();
  189.         h = anims[0]->getcurrentframe()->getheight();
  190.         
  191.         enemyfirecontrols[0].cmd = acmd_goto;
  192.         enemyfirecontrols[0].x = anims[0]->getx()+(w/2);
  193.         enemyfirecontrols[0].y = anims[0]->gety()+h+10;
  194.         enemyfirecontrols[0].speed = 6;
  195.         enemyfirecontrols[0].next = &enemyfirecontrols[1];
  196.         enemyfirecontrols[0].testproc = &testenemyfire;
  197.         
  198.         enemyfirecontrols[1].cmd = acmd_delete;
  199.         
  200.         anim->runcontrol(enemyfirecontrols);
  201.         anim->setpriority(-1);                
  202.     }
  203.  
  204.  
  205.     return FALSE;
  206. }
  207.  
  208. //*************************************
  209.  
  210. Boolean ACLWorld::collisions_advance(void)
  211. {
  212.     short     i;
  213.     Handle     ha;
  214.     Rect    rect;
  215.  
  216.     static short w,h,h2;
  217.  
  218.     step++;
  219.     
  220.     GetDItem(dialog,1,&i,&ha,&rect);
  221.     
  222.     switch(step)
  223.     {
  224.         case 1:
  225.         SetIText(ha,TEXTSTEP1);
  226.         
  227.         anims[0] = animbase->createanim(anim_pers);        
  228.         anims[1] = animbase->createanim(PICT_SIREN);
  229.  
  230.         anims[0]->findmaxsize(&w,&h);
  231.         anim_h = h;        
  232.         anims[0]->place( (backwidth/2)-(40+w), (backheight/2)-(h/2) );
  233.  
  234.         anims[1]->findmaxsize(NULL,&h2);
  235.         anims[1]->place( (backwidth/2)+40, ((backheight/2)-(h2/2))-(h2-h) );
  236.  
  237.         anims[2] = animbase->createanim(anim_song);
  238.         anims[2]->setanimflags(ANF_PINGPONG);
  239.         
  240.         anims[2]->setcollisionkey_me(1);        
  241.         anims[2]->setcollisionkey_hit(2);        
  242.         anims[0]->setcollisionkey_me(2);        
  243.         anims[0]->setcollisionkey_hit(1);        
  244.  
  245.         controls[0].cmd = acmd_place;
  246.         controls[0].x = anims[1]->getx()+7;
  247.         controls[0].y = anims[1]->gety()+10;
  248.         controls[0].testproc = &testrandomsong;
  249.         controls[0].next = &controls[1];
  250.  
  251.         controls[1].cmd = acmd_goto;
  252.         controls[1].speed = 1;
  253.         controls[1].x = anims[0]->getx()-(w+10);
  254.         controls[1].testproc = &testanimsong;
  255.         controls[1].next = &controls[0];
  256.  
  257.         anims[2]->runcontrol(controls);
  258.  
  259.         return FALSE;
  260.  
  261.         case 2:
  262.         SetIText(ha,TEXTSTEP2);        
  263.         
  264.         animbase->setsortflags(ASORT_PRIORITY);
  265.  
  266.  
  267.         for(i=0;i<3;i++) {delete anims[i]; anims[i]=NULL;}
  268.  
  269.         anims[0] = animbase->createanim(anim_spaceship);
  270.         anims[0]->setcollisionkey_me(2);
  271.         anims[0]->setcollisionkey_hit(1);
  272.         
  273.         anims[0]->findmaxsize(&w,&h);
  274.         anim_w = w;
  275.         anims[0]->place( (backwidth/2)-(w/2), backheight-(h+5) );
  276.  
  277.         spaceshipcontrols[0].cmd = acmd_move;
  278.         spaceshipcontrols[0].x = 0;
  279.         spaceshipcontrols[0].y = 0;
  280.         spaceshipcontrols[0].next = &spaceshipcontrols[0];
  281.         spaceshipcontrols[0].testproc = &testspaceship;
  282.         
  283.         anims[0]->runcontrol(spaceshipcontrols);
  284.  
  285.  
  286.         firecontrols[0].cmd = acmd_move;
  287.         firecontrols[0].x = 0;
  288.         firecontrols[0].y = -8;
  289.         firecontrols[0].next = &firecontrols[0];
  290.         firecontrols[0].testproc = &testfire;
  291.  
  292.         anims[1] = animbase->createanim(anim_enemy);
  293.         anims[1]->setcollisionkey_me(4);
  294.         anims[1]->setcollisionkey_hit(8);
  295.         
  296.         anims[1]->findmaxsize(&w,&h);
  297.  
  298.         enemycontrols[0].cmd = acmd_move;
  299.         enemycontrols[0].x = 2;
  300.         enemycontrols[0].y = 0;
  301.         enemycontrols[0].next = &enemycontrols[1];
  302.         
  303.         enemycontrols[1].cmd = acmd_place;
  304.         enemycontrols[1].x = -w;
  305.         enemycontrols[1].y = 18;
  306.         enemycontrols[1].testproc = &testenemy;
  307.         enemycontrols[1].next = &enemycontrols[0];
  308.  
  309.         anims[1]->runcontrol(enemycontrols);
  310.  
  311.         return FALSE;
  312.         
  313.         
  314.         case 3:
  315.         SetIText(ha,TEXTSTEP3);        
  316.         return FALSE;
  317.  
  318.         case 4:
  319.         SetIText(ha,TEXTSTEP4);        
  320.         return FALSE;
  321.  
  322.         case 5:
  323.         SetIText(ha,TEXTSTEP5);
  324.  
  325.         anims[2] = anims[0]->createanim(anim_field);
  326.         anims[2]->setcollisionkey_me(2);
  327.         anims[2]->setcollisionkey_hit(1);
  328.         anims[2]->setpriority(10);
  329.         anims[2]->place(-5,-13);
  330.             
  331.         return FALSE;
  332.         
  333.                         
  334.     }
  335.     
  336.     
  337.     return TRUE;
  338. }
  339.  
  340.  
  341.  
  342. //*************************************
  343.  
  344. Boolean ACLWorld::do_collisions(void)
  345. {
  346.     Point p;
  347.     char  key;
  348.     short res;
  349.     Boolean done = FALSE;
  350.     Anim  *anim;
  351.  
  352.     pleasewait(TRUE);
  353.  
  354.     ::animbase = animbase = new AnimBase();
  355.     
  356.     animbase->newgfx(PICT_SIREN);
  357.     animbase->newgfx(PICT_SHIPFIRE);
  358.     animbase->newgfx(PICT_ENEMYFIRE);
  359.     
  360.     animbase->preload_framedef(anim_pers);
  361.     animbase->preload_framedef(anim_song);
  362.     
  363.     animbase->preload_framedef(anim_spaceship);
  364.     animbase->preload_framedef(anim_enemy);
  365.  
  366.     animbase->preload_framedef(anim_field);
  367.  
  368.  
  369.     backwidth = 460;
  370.     backheight = 217;
  371.         
  372.     animbase->buildbuffer(460,217);
  373.     animbase->setbasex(17);
  374.     animbase->setbasey(8);
  375.  
  376.  
  377.     pleasewait(FALSE);
  378.  
  379.     step = 0;
  380.     openbasedialog();
  381.     SetWTitle(dialog,"\pCollisions");
  382.     collisions_advance();
  383.  
  384.     
  385.     for(;;)
  386.     {
  387.     
  388.         if (step>1)
  389.         {
  390.             anims[0]->setsequence(0);
  391.             anims[1]->setsequence(0);
  392.             if (anims[2]) anims[2]->setsequence(0,FALSE);
  393.         }
  394.     
  395.         res = processbasedialog(key,p);
  396.         
  397.         if         (res==DO_QUIT) {done=TRUE; break;}
  398.         else if (res==DO_MENU) break;
  399.         else if (res==DO_CONTINUE && collisions_advance()) break;
  400.         
  401.         else if (res==DO_KEY && step>1)
  402.         {
  403.             switch(key)
  404.             {
  405.                 case 28: spaceshipcontrols[0].x = -4; break;
  406.                 case 29: spaceshipcontrols[0].x = 4; break;
  407.                 
  408.                 case ' ':     anim = animbase->createanim(PICT_SHIPFIRE);
  409.                             anim->setcollisionkey_me(8);
  410.                             anim->setcollisionkey_hit(4);
  411.  
  412.                             anim->runcontrol(firecontrols);
  413.                             anim->place(anims[0]->getx()+23,anims[0]->gety());
  414.                             anim->setpriority(-1);
  415.                 break;
  416.             }
  417.         }
  418.         else if (res==DO_KEYUP && step>1)
  419.         {
  420.             switch(key)
  421.             {
  422.                 case 28:
  423.                 case 29: spaceshipcontrols[0].x = 0; break;
  424.             }
  425.         }        
  426.         
  427.     }
  428.     
  429.     closebasedialog();
  430.     
  431.     delete animbase;
  432.  
  433.     return done;
  434. }
  435.  
  436. //*************************************
  437.